/**
 * 
 */
package de.cbf.cam.dsa.tavern.carte.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;

import de.cbf.cam.dsa.tavern.carte.exceptions.WrongTypeProvidedException;
import de.cbf.cam.dsa.tavern.carte.model.entities.interfaces.IEditableEntity;
import de.cbf.cam.dsa.tavern.carte.model.entities.interfaces.INamedEntity;
import de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositeEntities;
import de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositePersistEntity;

/**
 * @author Stefan Alter
 *
 */
public class CompositeNamedEntities extends Composite 
		implements ICompositePersistEntity,ICompositeEntities{
	private List listEntity = null;
	/**
	 * @param parent
	 * @param style
	 */
	public CompositeNamedEntities(Composite parent, int style) {
		super(parent, style);
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
		GridLayout layout = new GridLayout(1,false);
			layout.marginWidth  = 0;
			layout.marginHeight = 0;
        GridData gDListEntity = new GridData();
	        gDListEntity.horizontalAlignment		= GridData.FILL;
	        gDListEntity.verticalAlignment			= GridData.FILL;
	        gDListEntity.grabExcessHorizontalSpace	= true;
	        gDListEntity.grabExcessVerticalSpace	= true;    
	        gDListEntity.widthHint					= 120;	        
        //
        this.setLayout(layout);
        //
        listEntity = new List(this, SWT.MULTI|SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL);
        listEntity.setLayoutData(gDListEntity);
		//
        registerListeners();        
	}

	private void registerListeners() {
		listEntity.addSelectionListener(selection);
		listEntity.addMouseListener(doubleClick);
		listEntity.addKeyListener(delete);		
	}

	@Override
	public Object getSelectedObject() {
		int index = listEntity.getSelectionIndex();
		if(index >=0){
			String nameSelected = listEntity.getItem(index);
			Object object = listEntity.getData(nameSelected);
			if (object instanceof INamedEntity) {
				INamedEntity entity = (INamedEntity) object;
				return entity;
			}
		}	
		return null;
	}
	@Override
	public IEditableEntity getSelectedEntity() {
		if (getSelectedObject() instanceof IEditableEntity) {
			IEditableEntity entity = (IEditableEntity) getSelectedObject();
			return entity;
		}
		return null;
	}
	
	@Override
	public Object[] getSelectedObjects() {
		String[] selection = listEntity.getSelection();
		if(selection.length == 0) return null;
		Object[] objects = new Object[selection.length];
		for (int i = 0; i < selection.length; i++) {
			Object object = listEntity.getData(selection[i]);
			objects[i] = object;
		}
		return objects;
	}
	@Override
	public IEditableEntity[] getSelectedEntities() {
		Object[] objects = getSelectedObjects();
		IEditableEntity[] resultArray = new IEditableEntity[0];
		java.util.List<IEditableEntity> resultList = new ArrayList<IEditableEntity>();
		for (int i = 0; i < objects.length; i++) {
			if (objects[i] instanceof IEditableEntity) {
				IEditableEntity entity = (IEditableEntity) objects[i];
				resultList.add(entity);
			}
		}
		return resultList.toArray(resultArray);
	}
	
	@Override
	public void setObjects(Iterator<? extends Object> iterator) {
		//save selection index
		int[] selection = listEntity.getSelectionIndices();
		listEntity.removeAll();
		while (iterator.hasNext()) {
			Object object = (Object) iterator.next();
			if (object instanceof INamedEntity) {
				INamedEntity entity = (INamedEntity) object;
				listEntity.add(entity.getName());
				//
				listEntity.setData(entity.getName(), entity);
			}
		}		
		//apply previous selection
		listEntity.setSelection(selection);
	}
	@Override
	public void setEntities(Iterator<IEditableEntity> iterator) {
		setObjects(iterator);		
	}
	@Override
	public void setSelectedEntity(IEditableEntity value)
			throws IllegalArgumentException {
		//check if value is of correct type
		if (value instanceof INamedEntity) {
			INamedEntity entity = (INamedEntity) value;
			//find entity ...
			int index = listEntity.indexOf(entity.getName());
			// and set selection
			listEntity.setSelection(index);
		}else{
			//value type is incorrect -> throw exception
			throw new WrongTypeProvidedException(INamedEntity.class,value.getClass());
		}
	}

	@Override
	public void deSelectAll() {
		listEntity.deselectAll();		
	}

	private Collection<ActionListener> selectionListeners = new ArrayList<ActionListener>();
	public boolean registerSelectionListener(ActionListener listener){
		return selectionListeners.add(listener);
	}
	public boolean deRegisterSelectionListener(ActionListener listener){
		return selectionListeners.remove(listener);
	}
	private SelectionAdvancer selection = new SelectionAdvancer();  //  @jve:decl-index=0:
	private class SelectionAdvancer extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			ActionEvent event = new ActionEvent(CompositeNamedEntities.this, ActionEvent.ACTION_PERFORMED, "Selection");
			for (ActionListener listener : selectionListeners) {
				listener.actionPerformed(event);
			}
		}		
	}
	private Collection<ActionListener> doubleClickListeners = new ArrayList<ActionListener>();
	public boolean registerDoubleClickListener(ActionListener listener){
		return doubleClickListeners.add(listener);
	}
	public boolean deRegisterDoubleClickListener(ActionListener listener){
		return doubleClickListeners.remove(listener);
	}
	private DoubleClickAdvancer doubleClick = new DoubleClickAdvancer();  //  @jve:decl-index=0:
	private class DoubleClickAdvancer extends MouseAdapter{
		@Override
		public void mouseDoubleClick(MouseEvent e) {
			ActionEvent event = new ActionEvent(CompositeNamedEntities.this, ActionEvent.ACTION_PERFORMED, "DoubleClick");
			for (ActionListener listener : doubleClickListeners) {
				listener.actionPerformed(event);
			}
		}	
	}
	
	private Collection<ActionListener> listChangedListeners = new ArrayList<ActionListener>();
	public boolean registerListChangedListener(ActionListener listener){
		return listChangedListeners.add(listener);
	}
	public boolean deRegisterListChangedListener(ActionListener listener){
		return listChangedListeners.remove(listener);
	}	
	public void notifyListChanged() {
		ActionEvent event = new ActionEvent(CompositeNamedEntities.this, ActionEvent.ACTION_PERFORMED, "ListChanged");
		for (ActionListener listener : listChangedListeners) {
			listener.actionPerformed(event);
		}
	}		
	
	
	private Collection<ActionListener> deleteListeners = new ArrayList<ActionListener>();
	public boolean registerDeleteListener(ActionListener listener){
		return deleteListeners.add(listener);
	}
	public boolean deRegisterDeleteListener(ActionListener listener){
		return deleteListeners.remove(listener);
	}
	private DeleteAdvancer delete = new DeleteAdvancer();
	
	private class DeleteAdvancer extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			if(e.keyCode == SWT.DEL){
				ActionEvent event = new ActionEvent(CompositeNamedEntities.this, ActionEvent.ACTION_PERFORMED, "Delete");
				for (ActionListener listener : deleteListeners) {
					listener.actionPerformed(event);
				}
			}			
		}		
	}

	
	

	
	

}  //  @jve:decl-index=0:visual-constraint="10,10"
